/* eslint-disable @typescript-eslint/no-explicit-any */
/**
 * 计算从开始时间到结束时间之间，每个月的天数列表，并包含星期信息。
 * @param startDate 开始时间
 * @param endDate 结束时间
 * @returns 一个Map，key为'YYYY年M月'格式的月份字符串，
 *          value为该月在时间段内的日期数组（'D日 星期X'格式）
 */
export function getDaysWithWeekdayPerMonthMap(
  startDate: Date,
  endDate: Date,
): Map<string, { text: string; isToday: boolean }[]> {
  const result = new Map<string, { text: string; isToday: boolean }[]>();
  const weekdays = [
    '星期日',
    '星期一',
    '星期二',
    '星期三',
    '星期四',
    '星期五',
    '星期六',
  ];

  if (startDate > endDate) {
    console.warn('开始时间晚于结束时间，返回空Map');
    return result;
  }

  // 获取今天的日期字符串，用于比较
  const today = new Date();
  today.setHours(0, 0, 0, 0);

  const current = new Date(startDate);
  // 将小时、分钟、秒和毫秒设置为0，避免因时间部分导致的比较问题
  current.setHours(0, 0, 0, 0);
  const end = new Date(endDate);
  end.setHours(0, 0, 0, 0);
  while (current <= end) {
    const year = current.getFullYear();
    const month = current.getMonth(); // 0-based, 0 is January
    const day = current.getDate();
    const weekday = current.getDay(); // 0 for Sunday, 1 for Monday, ...
    const monthKey = `${year}年${month + 1}月`;
    const dayValue = `${day}日 ${weekdays[weekday]}`;

    // 检查当前日期是否是今天
    const isToday = current.getTime() === today.getTime();

    if (!result.has(monthKey)) {
      result.set(monthKey, []);
    }
    result.get(monthKey)!.push({
      text: dayValue,
      isToday,
    });
    current.setDate(current.getDate() + 1);
  }
  return result;
}

/**
 * 将 Map 中所有 value 数组合并成一个单一数组。
 * @param map 输入的 Map，其 value 为数组。
 * @returns 包含所有 value 数组元素的新数组。
 */
export function flattenMapValues<T>(map: Map<any, T[]>): T[] {
  return Array.from(map.values()).flatMap(v => v);
}

/**
 * 防抖函数
 * @param fn 要执行的函数
 * @param delay 延迟时间
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number,
): (...args: Parameters<T>) => void {
  let timeout: number | null = null;
  return function (...args: Parameters<T>) {
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = window.setTimeout(() => {
      func(...args);
      if (timeout) {
        timeout = null;
      }
    }, wait);
  };
}
